package com.tanhua.server.service;

import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.commons.template.AliyunOssTemplate;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Video;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.domain.vo.VideoVO;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VideoApi;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class VideoService {
    @Reference
    private VideoApi videoApi;
    @Reference
    private UserInfoApi userInfoApi;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private AliyunOssTemplate ossTemplate;
    @Autowired
    private FastFileStorageClient dfsClient;
    @Autowired
    private FdfsWebServer fdfsWebServer;
    @Autowired
    private VideoMQService mqService;

    /**
     * 小视频列表
     */
//    @Cacheable(cacheNames = "videoList", key = "#page+'_'+#pagesize")
    public PageResult findVideoList(Integer page, Integer pagesize) {
        Long userId = UserHolder.getUser().getId();
        PageResult pageResult = null;
        pageResult = findByRedis(page, pagesize, userId);
        if (pageResult == null || pageResult.getItems().size() == 0) {
            pageResult = videoApi.findVideoList(page, pagesize, null);
        }
        List<Video> items = pageResult.getItems();
        //转换vo
        List<VideoVO> vos = new ArrayList<>();
        for (Video video : items) {
            VideoVO vo = new VideoVO();
            UserInfo userInfo = userInfoApi.findById(video.getUserId());
            BeanUtils.copyProperties(userInfo, vo);

            vo.setId(video.getId().toHexString());
            vo.setCover(video.getPicUrl());
            vo.setSignature(video.getText());
            BeanUtils.copyProperties(video, vo);

            Boolean hasLiked = redisTemplate.hasKey("video_like_" + userId + "_" + vo.getId());
            vo.setHasLiked(hasLiked ? 1 : 0);
            Boolean hasFocus = redisTemplate.hasKey("video_focus_" + userId + "_" + vo.getUserId());
            vo.setHasFocus(hasFocus ? 1 : 0);

            vos.add(vo);
        }
        pageResult.setItems(vos);
        return pageResult;
    }

    private PageResult findByRedis(Integer page, Integer pagesize, Long userId) {
        //QUANZI_VIDEO_RECOMMEND_1
        String strVids = redisTemplate.opsForValue().get("QUANZI_VIDEO_RECOMMEND_" + userId);
        if (strVids == null) {
            return null;
        }

        String[] arrVids = strVids.split(",");
        int count = arrVids.length;
        int pages = (int) Math.ceil(count * 1.0 / pagesize);
        if (page > pages) {
            return null;
        }

        //分页查询起始索引
        int index = (page - 1) * pagesize;
        int end = index + pagesize;
        if (end > count) {
            end = count;
        }

        List<Long> vidList = new ArrayList<>();
        for (int i = index; i < end; i++) {
            vidList.add(Long.parseLong(arrVids[i].toString()));
        }

        List<Video> videoList = videoApi.findListByPids(vidList);


        return new PageResult(count, pagesize, pages, page, videoList);
    }

    /**
     * 视频上传
     */
//    @CacheEvict(cacheNames = "videoList", allEntries = true)
    public ResponseEntity uploadVideo(MultipartFile image, MultipartFile videoFile) throws IOException {
        Long userId = UserHolder.getUser().getId();
        //1. 将封面文件上传至阿里云
        String picUrl = ossTemplate.upload(image.getInputStream(), image.getOriginalFilename());
        //2. 将视频文件使用fastdfs上传值本地文件存储服务器
        String suffix = videoFile.getOriginalFilename().substring(videoFile.getOriginalFilename().lastIndexOf(".") + 1);
        StorePath storePath = dfsClient.uploadFile(videoFile.getInputStream(), videoFile.getSize(), suffix, null);
        String videoUrl = fdfsWebServer.getWebServerUrl() + storePath.getFullPath();
        //3. 封装video
        Video video = new Video();
        video.setUserId(userId);
        video.setText("我就是我");
        video.setPicUrl(picUrl);
        video.setVideoUrl(videoUrl);
        video.setLikeCount(0);
        video.setLoveCount(0);
        video.setCommentCount(0);
        //4. 保存video到数据库
        String videoId = videoApi.save(video);

        //发送mq消息，用于大数据推荐
        mqService.sendSaveVideoMsg(videoId);
        return ResponseEntity.ok(null);
    }

    /**
     * 关注视频用户
     * @param targetId 发布视频的用户id
     * @return  null
     */
    public ResponseEntity saveUserFocus(Long targetId) {
        Long userId = UserHolder.getUser().getId();
        videoApi.saveUserFocus(userId, targetId);
        //注意： 将关注状态存入redis
        redisTemplate.opsForValue().set("video_focus_" + userId + "_" + targetId,"1");
        return ResponseEntity.ok(null);
    }

    /**
     * 取消关注视频用户
     * @param targetId  发布视频的用户id
     * @return null
     */
    public ResponseEntity removeUserFocus(Long targetId) {
        Long userId = UserHolder.getUser().getId();
        videoApi.removeUserFocus(userId, targetId);
        //从redis中删除关注记录
        redisTemplate.delete("video_focus_" + userId + "_" + targetId);
        return ResponseEntity.ok(null);
    }
}
